package org.numanint.code;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;

import org.numanint.wizard.WebProjectConfig;
import org.numanint.wizard.WebProjectDBConfig;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class Generator {
	public final static String TMPLATE_DIR = "/org/numanint/template";
	public final static String FILE_ENCODE = "UTF-8";
	private String templateFilename;
	private String outputDir;



	private GeneratorProperties properties;
	private HashMap<String,Object> data;
	
	public Generator(GeneratorProperties properties){
		this.properties = properties;
	}

	public GeneratorProperties getProperties() {
		return properties;
	}
	public void setProperties(GeneratorProperties properties) {
		this.properties = properties;
	}

	public String getTemplateFilename() {
		return templateFilename;
	}
	public void setTemplateFilename(String templateFilename) {
		this.templateFilename = templateFilename;
	}
	public HashMap<String, Object> getData() {
		return data;
	}

	public void setData(HashMap<String, Object> data) {
		this.data = data;
	}
	
	public String getOutputDir() {
		return outputDir;
	}
	
	public void setOutputDir(String outputDir) {
		if(outputDir!=null)
			if(outputDir.lastIndexOf(System.getProperty("file.separator"))!=outputDir.length()-1)
				outputDir = outputDir+System.getProperty("file.separator");
		this.outputDir = outputDir;
		
	}

    public void generator() throws Exception {
    	Configuration cfg = new Configuration();
    	cfg.setClassForTemplateLoading(Generator.class,TMPLATE_DIR);
    	cfg.setNumberFormat("0.##########");
    	cfg.setLocale(Locale.CHINA); 
    	cfg.setDefaultEncoding(FILE_ENCODE);
    	cfg.setEncoding(Locale.CHINA,FILE_ENCODE);
    	Template template = cfg.getTemplate(templateFilename);
    	template.setEncoding(FILE_ENCODE);
    	template.setOutputEncoding(FILE_ENCODE);
    	Iterator<String> it = data.keySet().iterator();
    	while(it.hasNext()){    		
    		String filename = it.next();
    		String outputFilename = outputDir+filename;
    		outputFilename = outputFilename.replace('/', System.getProperty("file.separator").charAt(0));
    		File f = new File(outputFilename.substring(0,outputFilename.lastIndexOf(System.getProperty("file.separator"))));
    		if(!f.exists()) f.mkdirs();
    		FileOutputStream fos = new FileOutputStream(new File(outputFilename));
    		template.process(data.get(filename), new OutputStreamWriter(fos,FILE_ENCODE));
    		fos.flush();
    		fos.close();
    		System.out.println("Generator code: "+outputFilename);    		
    	}
    }
	
    public static String getSchema(){
    	return "MZDEV";
    }
	
	public static Connection getConnection()throws Exception{
		WebProjectConfig.projectDBConfig =new WebProjectDBConfig("oracle.jdbc.driver.OracleDriver",
				"jdbc:oracle:thin:@192.168.4.201:1521:cring",
				"mzdev","mzdev");
		Class.forName(WebProjectConfig.projectDBConfig.driver);
		return DriverManager.getConnection( 
   			 WebProjectConfig.projectDBConfig.url,
   			 WebProjectConfig.projectDBConfig.username,
   			 WebProjectConfig.projectDBConfig.password);
	}
	
	public static String[] getTableNames(){
		String[] tableNames = {
				"SERVICE",
				"SERVICE_NODE",                        
				"SERVICE_CALLER",                 
				"SERVICE_CENTER",  
				"SERVICE_NODE_BIND",              
				"SERVICE_OPERATION",              
				"SERVICE_OPERATION_LICENSE",      
				"SERVICE_OPERATION_LOG",          
				"SERVICE_PROVIDER"   
				};
		return tableNames;
	}
	
	
	public void generatorAll(ReverseEngineer reveng) throws Exception{
		
		PojoGenerator pojoGenerator = new PojoGenerator(properties);
		pojoGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		pojoGenerator.setTemplateFilename("pojo.ftl");
		pojoGenerator.generator(reveng);
		
		HbmGenerator hbmGenerator = new HbmGenerator(properties);
		hbmGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		hbmGenerator.setTemplateFilename("hbm.ftl");
		hbmGenerator.generator(reveng);
		
		DaoGenerator daoGenerator = new DaoGenerator(properties);
		daoGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		daoGenerator.setTemplateFilename("dao.ftl");
		daoGenerator.generator(reveng);
		
		BaseDaoGenerator baseDaoGenerator = new BaseDaoGenerator(properties);
		baseDaoGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		baseDaoGenerator.setTemplateFilename("baseDao.ftl");
		baseDaoGenerator.generator(reveng);
		
		HibernateCfgGenerator hibernateCfgGenerator = new HibernateCfgGenerator(properties);
		hibernateCfgGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		hibernateCfgGenerator.setTemplateFilename("hibernate.cfg.ftl");
		hibernateCfgGenerator.generator(reveng);	

		BoGenerator boGenerator = new BoGenerator(properties);			
		boGenerator.setProperties(properties);
		boGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		boGenerator.setTemplateFilename("bo.ftl");
		boGenerator.generator(reveng);
		
		ControllerGenerator controllerGenerator = new ControllerGenerator(properties);
		controllerGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		controllerGenerator.setTemplateFilename("controller.ftl");
		controllerGenerator.generator(reveng);
		
		SuperMultiActionControllerGenerator superMultiActionControllerGenerator = new SuperMultiActionControllerGenerator(properties);
		superMultiActionControllerGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		superMultiActionControllerGenerator.setTemplateFilename("superMultiActionController.ftl");
		superMultiActionControllerGenerator.generator(reveng);
		
		
		ValidatorGenerator validatorGenerator = new ValidatorGenerator(properties);
		validatorGenerator.setOutputDir(properties.getProjectDir()+properties.getSrcDir()+"/");
		validatorGenerator.setTemplateFilename("validator.ftl");
		validatorGenerator.generator(reveng);

		DaoXmlGenerator daoXmlGenerator = new DaoXmlGenerator(properties);
		daoXmlGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/WEB-INF/daoXml/");
		daoXmlGenerator.setTemplateFilename("dao.xml.ftl");
		daoXmlGenerator.generator(reveng);


		BoXmlGenerator boXmlGenerator = new BoXmlGenerator(properties);
		boXmlGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/WEB-INF/boXml/");
		boXmlGenerator.setTemplateFilename("bo.xml.ftl");
		boXmlGenerator.generator(reveng);
		
		ControllerXmlGenerator controllerXmlGenerator = new ControllerXmlGenerator(properties);
		controllerXmlGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/WEB-INF/controllerXml/");			
		controllerXmlGenerator.setTemplateFilename("controller.xml.ftl");
		controllerXmlGenerator.generator(reveng);
		
		ValidatorXmlGenerator validatorXmlGenerator = new ValidatorXmlGenerator(properties);
		validatorXmlGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/WEB-INF/validatorXml/");			
		validatorXmlGenerator.setTemplateFilename("validator.xml.ftl");
		validatorXmlGenerator.generator(reveng);			
		
		ListJspGenerator listJspGenerator = new ListJspGenerator(properties);
		listJspGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/"+ConventUtils.lowerFirstChar(properties.getProjectName())+"/"+properties.getSampleName()+"/");
		listJspGenerator.setTemplateFilename("jsp/list.jsp.ftl");
		listJspGenerator.generator(reveng);	
		
		AddJspGenerator addJspGenerator = new AddJspGenerator(properties);
		addJspGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/"+ConventUtils.lowerFirstChar(properties.getProjectName())+"/"+properties.getSampleName()+"/");
		addJspGenerator.setTemplateFilename("jsp/add.jsp.ftl");
		addJspGenerator.generator(reveng);	
		
		EditJspGenerator editJspGenerator = new EditJspGenerator(properties);
		editJspGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/"+ConventUtils.lowerFirstChar(properties.getProjectName())+"/"+properties.getSampleName()+"/");
		editJspGenerator.setTemplateFilename("jsp/edit.jsp.ftl");
		editJspGenerator.generator(reveng);	
		
		ShowJspGenerator showJspGenerator = new ShowJspGenerator(properties);
		showJspGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/"+ConventUtils.lowerFirstChar(properties.getProjectName())+"/"+properties.getSampleName()+"/");
		showJspGenerator.setTemplateFilename("jsp/show.jsp.ftl");
		showJspGenerator.generator(reveng);	
		
		IndexJspGenerator indexJspGenerator = new IndexJspGenerator(properties);
		indexJspGenerator.setOutputDir(properties.getProjectDir()+properties.getWebContent()+"/"+ConventUtils.lowerFirstChar(properties.getProjectName())+"/"+properties.getSampleName()+"/");
		indexJspGenerator.setTemplateFilename("jsp/index.jsp.ftl");
		indexJspGenerator.generator(reveng);
	}
    
	public static void main(String[] args){
		try{
			
			GeneratorProperties properties = new GeneratorProperties();
			properties.setProjectName("BlankFramework");
			properties.setProjectDir("/home/serj/framework/workspace/BlankFramework/");
			properties.setWebRoot("");
			properties.setSrcDir("src");
			properties.setWebContent("WebContent");
			properties.setSampleName("sample");
			properties.setPojoPkgName("org.xwlabs.pojo");
			properties.setDaoPkgName("org.xwlabs.dao");
			properties.setBoPkgName("org.xwlabs.bo");
			properties.setControllerPkgName("org.xwlabs.controller");
			properties.setValidatorPkgName("org.xwlabs.validator");
			Generator generator = new Generator(properties);
			ReverseEngineer reveng = new ReverseEngineer(getConnection(),getTableNames(),getSchema());
			reveng.reverse(	);
			generator.generatorAll(reveng);
										
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}
